#version 120

uniform sampler2D backfacetexture;
uniform sampler3D volumetexture;
uniform sampler3D gradvolume;
uniform sampler2D litsphere;

uniform sampler1D tranf;

uniform float stepsize;
uniform float begin;

varying vec4 vposition;
varying vec3 viewVec;
uniform vec4 lightposition;
uniform float isValue;
uniform mat4 rotation_normal_x;
uniform mat4 rotation_normal_y;

vec4 pos;





float offset(vec2 xy)
{
	return fract((xy.x)*1.298/10+(xy.y)/10)/800;
}

float calculateAngle(vec3 normal, vec3 lastnormal)
{
	float angle;
	angle=acos(dot(normal, lastnormal)/(length(normal)*length(lastnormal)));

	return angle;
}

vec3 getNormal(vec3 normal)
{
	normal = (normalize(normal*2-vec3(1,1,1)));
    normal = gl_NormalMatrix*normal;
    //normal = abs(normalize(normal));
	return normal;
}

bool testContour(vec3 vec, vec3 delta_dir)
{
	vec3 normal, lastnormal;
	lastnormal = getNormal(texture3D(gradvolume, vec).xyz);
	normal = getNormal(texture3D(gradvolume, vec+delta_dir).xyz);
	float T = 0.003;
	float Kv = calculateAngle(normal, lastnormal)/(length(delta_dir));
	float length_NdotV = length(dot(normal,normalize(viewVec.xyz)));
	if(length_NdotV*length_NdotV<=T*Kv*(2-T*Kv))
	//if(length(dot(lastnormal, normalize(viewVec.xyz)))<0.4)  // dot(V,N) simple contour
		return true;

	return false;
}


void main()
{
	vec2 texposition = ((vposition.xy/vposition.w) + 1.0)/2.0;

	vec2 interleavePosf = vec2(texposition.x*1600, texposition.y*1200);
	ivec2 interleavePos;
	interleavePos.x = int(floor(interleavePosf.x + 0.5));
	interleavePos.y = int(floor(interleavePosf.y + 0.5));

	interleavePos.x = int(mod(interleavePos.x,8));
	interleavePos.y = int(mod(interleavePos.y,8));

	float offset = offset(interleavePos);

	vec4 start = gl_TexCoord[0];
	pos = start*2.0;
	vec3 dir;
	vec4 backposition1 = texture2D(backfacetexture, texposition);
	dir.x = backposition1.x - start.x;
	dir.y = backposition1.y - start.y;
	dir.z = backposition1.z - start.z;
	float len = length(dir);
	vec3 norm_dir = normalize(dir);
	float length_acc = 0;

   float delta = stepsize;
   vec3 delta_dir = norm_dir * delta;
   float delta_dir_len = length(delta_dir);
   vec3 vec = start.xyz;

   float color_sample;
   float lastcolor_sample;

   float finestepsize = -1;

  for(int i = 0; i < 400; i++)
    {
      color_sample = texture3D(volumetexture,vec).x;
	  if(color_sample > isValue)
	  {
		  break;
	  }
	  vec += delta_dir;
      length_acc += delta_dir_len;
	  if(length_acc >= len)
		  discard;
  }

  vec3 delta_e = delta_dir/2;
  vec -= delta_e;
  length_acc -= length(delta_e);
  		  
  for(int j=0; j<7; j++)
  {
      color_sample = texture3D(volumetexture,vec).x;
	  if(color_sample < isValue)
	  {
		  vec += delta_e;
		  length_acc += length(delta_e);
	  }
	  else
	  {
		  vec -= delta_e;
		  length_acc -= length(delta_e);
	  }
	  delta_e = delta_e/2;
  }
  
  //vec = HitpointRefinement(vec, delta_dir, color_sample);  
  vec3 normal = texture3D(gradvolume, vec).xyz;
  normal = getNormal(normal);

  //if(testContour(vec, delta_dir)/*length(dot(normal, normalize(viewVec.xyz)))<0.4*/)
	 // gl_FragColor = vec4(0,0,0,1);
  //else
	//gl_FragColor = vec4(texture2D(litsphere,((vec4(normal,0)*rotation_normal_x*rotation_normal_y).xy/2.0*0.9+vec2(0.5,0.5))).xyz,1);
    vec3 right = vposition.xyz/vposition.w + 3*length_acc*normalize(viewVec);
	//vec4 temp = gl_ModelViewProjectionMatrix*pos;
	 //gl_FragColor = gl_ModelViewProjectionMatrix*vec4(vec*2,0);
   //gl_FragColor = vec4(normalize((vec4(normal,0)*rotation_normal_x).xyz),1);

    gl_FragColor = vec4(vec,1);

		 
	  
}

